package org.akushe.core.repository;

import java.util.Hashtable;

import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.xml.transform.TransformerFactoryConfigurationError;

import org.akushe.core.config.Configuration;
import org.apache.jackrabbit.core.jndi.RegistryHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RepositoryServiceImpl implements IRepositoryService{

	private static final Logger log = LoggerFactory.getLogger(RepositoryServiceImpl.class);

	private Hashtable<String, String> jndiEnv ;
	
	private static final String REPOSITORY_BINDING_NAME = "akhushe-simple-repository";
	
	private Repository repository;

	private void loadJndiPrms(){

		if(jndiEnv == null){
			jndiEnv = new Hashtable<String, String>();
			jndiEnv.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.jackrabbit.core.jndi" + ".provider.DummyInitialContextFactory");

			jndiEnv.put(Context.PROVIDER_URL, "localhost");				
		}
	
	}

	public void initRepository() throws RepositoryException{
		
		String configFile = Configuration.getInstance().getRepositoryConfigFile();
		String repHomeDir = Configuration.getInstance().getRepositoryHome();

		this.loadJndiPrms();
		
		InitialContext ctx;
		try {
			ctx = new InitialContext(jndiEnv);
			RegistryHelper.registerRepository(ctx, REPOSITORY_BINDING_NAME,
					 configFile,
					 repHomeDir,
					 true);			

			repository = (Repository) ctx.lookup(REPOSITORY_BINDING_NAME);	
			
		} catch (NamingException e) {
            log.error("Unable to initialize repository: " + e.getMessage(), e);
            throw new RepositoryException(e);
        }
        catch (RepositoryException e) {
            log.error("Unable to initialize repository: " + e.getMessage(), e);
            throw new RepositoryException(e);
        }
        catch (TransformerFactoryConfigurationError e) {
            log.error("Unable to initialize repository: " + e.getMessage(), e);
            throw new RepositoryException(e);
        }
	}

	public void shutdownRepository() throws RepositoryException{
		
		this.loadJndiPrms();
		
		log.info("Shutting down repository bound to '{}'", REPOSITORY_BINDING_NAME);

        try {
            Context ctx = new InitialContext(jndiEnv);
            RegistryHelper.unregisterRepository(ctx, REPOSITORY_BINDING_NAME);
        } catch (NamingException e) {
            log.warn("Unable to shutdown repository " + REPOSITORY_BINDING_NAME + ": " + e.getMessage(), e);
        } catch (Throwable e) {
            log.error("Failed to shutdown repository " + REPOSITORY_BINDING_NAME + ": " + e.getMessage(), e);
        }
		
	}
	
	public Repository getRepository() throws RepositoryException{
		return repository;
	}

}
